/* *****************************************************************************

  Copyright (C), 2023-2023, Huawei Tech. Co., Ltd.

 ******************************************************************************
  File Name     : hisec_npu_cmd_defs.h
  Version       : Initial Draft
  Created       : 2023/8/21
  Last Modified :
  Description   : secure commands between Driver and MPU/uCode
  Function List :
***************************************************************************** */

#ifndef HISEC_NPU_CMD_DEFS_H
#define HISEC_NPU_CMD_DEFS_H

#include "mpu_cmd_base_defs.h"

#ifndef BIG_ENDIAN
#define BIG_ENDIAN 0x4321
#endif

#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 0x1234
#endif

#define RESP_DATA_LEN_MAX 32

/**
 * @brief hisec command common header
 *
 */
typedef struct tag_hisec_cmd_hdr {
    union {
        struct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
            u32 rsvd0 : 16;

            /** Logical concurrency channel */
            u32 channel_id : 8;

            /** Command type, @see hisec_npu_cmd_type_e */
            u32 cmd_type : 8;
#else
            /** Command type, @see hisec_npu_cmd_type_e */
            u32 cmd_type : 8;

            /** Logical concurrency channel */
            u32 channel_id : 8;
            u32 rsvd0 : 16;
#endif
        } bs;
        u32 value;
    } dw0;

    /** Command serial number */
    u32 cmd_sn;
    u32 rsvd1[2];
} hisec_cmd_hdr_s;

/**
 * @brief HiSec init scqc command struct defination
 * @see HISEC_NPU_CMD_INIT_SCQC
 *
 */
typedef struct tag_hisec_cmd_init_scqc {
    hisec_cmd_hdr_s cmdhdr;

    u32 scqn;
    u32 rsvd;
    u32 scqc[10];
} hisec_cmd_init_scqc_s;

/**
 * @brief Hisec deinit scqc command struct defination
 * @see HISEC_NPU_CMD_DEINIT_SCQC
 *
 */
typedef struct tag_hisec_cmd_deinit_scqc {
    hisec_cmd_hdr_s cmdhdr; /**< HISec command header */

    u32 scqn;
    u32 resvd[11];
} hisec_cmd_deinit_scqc_s;

/**
 * @brief HISec flush ipsec resource struct defination
 * @see HISEC_NPU_CMD_FLUSH_IPSEC_RES
 *
 */
typedef struct tag_hisec_cmd_flush_ipsec_res {
    hisec_cmd_hdr_s cmdhdr; /**< HISec command header */

    u16 func_id;
    u16 rsvd0;
    u32 flush_flag;
    u32 rsvd1;
} hisec_cmd_flush_ipsec_res_s;

/**
 * @brief HISec SA encrypt information
 *
 */
typedef struct tag_hisec_sa_enc_info {
    union {
        struct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
            u32 proto : 8;     /**< tcp/udp */
            u32 direction : 8; /**< out/in */
            u32 mode : 8;      /**< 0 transport/ 1 tunnel */
            u32 flag : 8;      /**< 1 -esn */
#else
            u32 flag : 8;
            u32 mode : 8;
            u32 direction : 8;
            u32 proto : 8;
#endif
        } bs;
        u32 value;
    } enc_dw0;

    union {
        struct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
            u32 replaywindow : 16; /**< 32-64 */
            u32 alg_type : 8;      /**< 0- aead 1-enc 2-auth 3-enc & auth */
            u32 alg_standard : 8;  /**< 0 - aes, 3 - SM4 */
#else
            u32 alg_standard : 8;
            u32 alg_type : 8;
            u32 replaywindow : 16;
#endif
        } bs;
        u32 value;
    } enc_dw1;

    union {
        struct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
            u32 enc_type : 8;        /**< hisec_crypto_alg_type */
            u32 auth_type : 8;       /**< hisec_crypto_alg_type */
            u32 cipher_key_len : 16; /**< in  bit */
#else
            u32 cipher_key_len : 16;
            u32 auth_type : 8;
            u32 enc_type : 8;
#endif
        } bs;
        u32 value;
    } enc_dw2;

    union {
        struct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
            u32 auth_key_len : 16;   /**< in bit  */
            u32 auth_trunc_len : 16; /**< in bit  */
#else
            u32 auth_trunc_len : 16;
            u32 auth_key_len : 16;
#endif
        } bs;
        u32 value;
    } enc_dw3;

    union {
        struct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
            u32 icv_mac_len : 16; /**< in bit  */
            u32 rsvd1 : 16;
#else
            u32 rsvd1 : 16;
            u32 icv_mac_len : 16;

#endif
        } bs;
        u32 value;
    } enc_dw4;

    u32 salt; /**< 32bit */

    u32 pad[2];

    u32 cipher_key[8]; /**< 128bit 192bit 256bit	*/
    u32 auth_key[8];   /**< 256bit */
} hisec_sa_enc_info_s;

/**
 * @brief HISec SA tuples
 *
 */
typedef struct tag_hisec_sa_tuples {
    u32 daddr[4]; /**< ipv4 in daddr[0] */
    u32 spi;

    union {
        struct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
            u32 ipsec_proto : 8;
            u32 iptype : 8; /**< 0-ipv4 1-ipv6 */
            u32 rsvd : 16;
#else
            u32 rsvd : 16;
            u32 iptype : 8;
            u32 ipsec_proto : 8;
#endif
        } bs;
        u32 value;
    } tup_dw0;

    u32 pad[2];
} hisec_sa_tuples_s;

/**
 * @brief  IPsec SA msg 160B struct defination
 * @see HISEC_NPU_CMD_SET_IPSEC_SA
 *
 */
typedef struct tag_hisec_cmd_set_ipsec_sa {
    hisec_cmd_hdr_s cmdhdr; /**< HISec command header, 16B */

    hisec_sa_tuples_s tuples; /**< 32B */

    union {
        struct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
            u32 opid : 8; /**< 0-add 1-del 2-update 3-flush */
            u32 rsvd0 : 24;
#else
            u32 rsvd0 : 24;
            u32 opid : 8;
#endif
        } bs;
        u32 value;
    } sa_dw0;

    u32 scqn; /**< used for scqe sa aging update msg notify */

    u32 pad[2];

    hisec_sa_enc_info_s enc_info;
} hisec_cmd_set_ipsec_sa_s;

/**
 * @brief HISec SP tuples
 *
 */
typedef struct tag_hisec_sp_tuples {
    u32 saddr[4]; /**< ipv4 in saddr[0] */
    u32 daddr[4]; /**< ipv4 in daddr[0] */
    u32 sa_masklen;
    u32 da_masklen;

    union {
        struct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
            u32 dport : 16;
            u32 sport : 16;
#else
            u32 sport : 16;
            u32 dport : 16;
#endif
        } bs;
        u32 value;
    } tup_dw0;

    union {
        struct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
            u32 dport_mask : 16;
            u32 sport_mask : 16;
#else
            u32 sport_mask : 16;
            u32 dport_mask : 16;
#endif
        } bs;
        u32 value;
    } tup_dw1;

    union {
        struct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
            u32 ulp_proto : 8; /**<  tcp/udp */
            u32 iptype : 8;    /**< 0-ipv4 1-ipv6 */
            u32 rsvd0 : 16;
#else
            u16 rsvd0;
            u8 iptype;
            u8 ulp_proto;
#endif
        } bs;
        u32 value;
    } tup_dw2;

    u32 pad[3];
} hisec_sp_tuples_s;

/**
 * @brief HISec set ipsec SP command struct defination
 * @see HISEC_NPU_CMD_SET_IPSEC_SP, IPsec SP msg 128B
 *
 */
typedef struct tag_hisec_cmd_set_ipsec_sp {
    hisec_cmd_hdr_s cmdhdr; /**< HISec command header */
    hisec_sp_tuples_s tuples;
    u32 spi;
    union {
        struct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
            u32 ipsec_proto : 8; /**< 50-esp 51-ah */
            u32 opid : 8;        /**< 0-add 1-del 2-update */
            u32 action : 8; /**< 0-bypass 1-encrypted */
            u32 rsvd0 : 8;
#else
            u32 rsvd0 : 8;
            u32 action : 8;
            u32 opid : 8;
            u32 ipsec_proto : 8;
#endif
        } bs;
        u32 value;
    } sp_dw0;

    u32 pad[10];
} hisec_cmd_set_ipsec_sp_s;

/**
 * @brief HISec DH parameters, used by hisec_cmd_calc_dh_s
 *
 */
typedef struct tag_hisec_cmd_dh_param {
#if (BYTE_ORDER == LITTLE_ENDIAN)
    u16 generator;
    /** DH phase, 1:DH Phase1 2:DH Phase 2 */
    u8 dh_phase;
    /** DH group id */
    u8 dh_groupid;
#else
    /** DH group id */
    u8 dh_groupid;
    /** DH phase, 1:DH Phase1 2:DH Phase 2 */
    u8 dh_phase;
    u16 generator;
#endif

#if (BYTE_ORDER == LITTLE_ENDIAN)
    u16 privkey_len;
    u16 modp_len;
#else
    u16 modp_len;
    u16 privkey_len;
#endif

#if (BYTE_ORDER == LITTLE_ENDIAN)
    u16 rsvd0;
    u16 pubkey_len;
#else
    u16 pubkey_len;
    u16 rsvd0;
#endif

    u32 rsvd1[13];

    u32 modprime[128];    /**< public prime number */
    u32 private_key[128]; /**< private Xa */
    u32 public_key[128];  /**< public Yb */
} hisec_cmd_dh_param_s;

/**
 * @brief HISec calculate DH command struct defination
 * @see HISEC_NPU_CMD_CALC_DH
 *
 */
typedef struct tag_hisec_cmd_calc_dh {
    hisec_cmd_hdr_s cmdhdr; /**< HISec command header */

    /** writeback result PhyAddr */
    u32 buf_len;
    u32 buf_gpah;
    u32 buf_gpal;

    /** writeback result LogicalVirtualAddr */
    u32 buf_vah;
    u32 buf_val;

    /** detect memory tramp */
    u32 magic_h;
    u32 magic_l;

    u32 scqn;
    u32 rsvd[4];

    hisec_cmd_dh_param_s dh_param;
} hisec_cmd_calc_dh_s;

/**
 * @brief HISec hardware random calculation response data, used by hisec_cmd_trng_module_s
 *
 */
typedef struct trng_data_resp {
    u32 status;
    u32 data_out[RESP_DATA_LEN_MAX];
} trng_data_resp_s;

/**
 * @brief HISec hardware random command struct defination
 * @see HISEC_NPU_CMD_HW_RANDOM
 *
 */
typedef struct hisec_cmd_trng_module {
    hisec_cmd_hdr_s cmdhdr; /**< HISec command header */
    u32 length;
    trng_data_resp_s resp;
} hisec_cmd_trng_module_s;

#endif /* HISEC_NPU_CMD_DEFS_H */
